import { defineComponent, markRaw, ref, nextTick } from 'vue'
import DataNode from '../../ItemNode/DataNode'
import {
  ElButton,
  ElColorPicker,
  ElForm,
  ElFormItem,
  ElIcon,
  ElInput,
  ElInputNumber,
  ElPopover,
  ElRadioButton,
  ElRadioGroup,
  ElSwitch,
  ElTag,
  ElText
} from 'element-plus'
import classes from '../../ItemNode/ItemNode.module.css'
import CartesianChart from './CartesianChart.vue'
import CartesianChartRaw from './CartesianChart.vue?raw'
import barRenderItemRaw from './barRenderItem.js?raw'
import { Edit, Minus, Plus } from '@element-plus/icons-vue'
import Tip from '../../panel/Tip.vue'

export default class NCartesianChart extends DataNode {
  isNCartesianChart = true
  isChartNode = true

  constructor(node?: NCartesianChart) {
    super(node)

    if (!node) {
      this.path = './components/NCartesianChart/NCartesianChart.tsx'
      this.name = '直角坐标图'

      const style = this.props.style
      this.props.style = {
        ...style,
        width: '300px',
        height: '200px',
        flexShrink: '0'
      }

      this.props.dataUrl = ''
      this.props.dataFn = `function () {
  return [
    {
      product: 'defaultA',
      default1: 2,
      default2: 4
    },
    {
      product: 'defaultB',
      default1: 5,
      default2: 2
    },
    {
      product: 'defaultC',
      default1: 4,
      default2: 3
    },
    {
      product: 'defaultD',
      default1: 6,
      default2: 1
    }
  ];
}`

      this.props.autoAction = false

      this.props.option = {
        color: ['hsla(210, 100%, 67%, 1)', 'hsla(30, 100%, 67%, 1)'],
        colorLinear: false,
        barWidth: null,
        smooth: false,
        axisLabelColor: '#333',
        legendTextStyleColor: '#333',
        yAxis: [{ name: '' }],
        datasetSourceProduct: 'product',
        series: [
          {
            name: 'default1',
            type: 'bar',
            yAxisIndex: 0
          },
          {
            name: 'default2',
            type: 'line',
            yAxisIndex: 0
          }
        ]
      }
    }

    const pComponent = this.component
    this.component = markRaw(
      defineComponent(
        (props) => {
          return () => (
            <pComponent>
              <CartesianChart
                option={this.props.option}
                data={this.props.data ?? []}
                autoAction={this.props.autoAction}
              ></CartesianChart>
            </pComponent>
          )
        },
        {
          name: 'NCartesianChart'
        }
      )
    )

    const pView = this.view
    this.view = markRaw(
      defineComponent((props) => {
        return () => (
          <pView>
            <this.component style={{ transform: 'scale(0.35, 0.3)' }}></this.component>
          </pView>
        )
      })
    )

    const pParams = this.params
    this.params = markRaw(
      defineComponent(() => {
        const yAxisRef = ref()
        const yAxisVisible = ref(false)
        const yAxisValue = ref()

        return () => (
          <pParams>
            <div class={classes['params-item']}>
              <ElText class={classes['params-item-label']} type="info">
                x坐标轴字段
              </ElText>
              <div class={classes['params-item-content']}>
                <ElInput
                  modelValue={this.props.option.datasetSourceProduct}
                  onUpdate:modelValue={(v) => (this.props.option.datasetSourceProduct = v || '')}
                  size="small"
                ></ElInput>
              </div>
            </div>
            <div class={classes['params-item']}>
              <ElText class={classes['params-item-label']} type="info">
                y坐标轴名
              </ElText>
              <div class={classes['params-item-content']}>
                {this.props.option.yAxis.map((item, index) => (
                  <ElTag
                    key={index}
                    closable={this.props.option.yAxis.length !== 1}
                    type="primary"
                    size="small"
                    onClose={() => this.props.option.yAxis.splice(index, 1)}
                  >
                    {{
                      default: () => {
                        return (
                          <span
                            style={{
                              flex: '1',
                              display: 'flex',
                              justifyContent: 'space-between'
                            }}
                          >
                            <span>
                              索引：{index}，名：{item.name}
                            </span>
                            <span>
                              <ElPopover
                                width={200}
                                trigger="click"
                                teleported={false}
                                placement="top"
                              >
                                {{
                                  reference: () => (
                                    <ElIcon color="var(--el-color-primary)">
                                      <Edit></Edit>
                                    </ElIcon>
                                  ),
                                  default: () => {
                                    const name = ref(item.name)

                                    return (
                                      <>
                                        <ElForm label-width="60px">
                                          <ElFormItem label="坐标轴名">
                                            <ElInput
                                              v-model={name.value}
                                              size="small"
                                              onChange={(v) => (item.name = v)}
                                            ></ElInput>
                                          </ElFormItem>
                                        </ElForm>
                                      </>
                                    )
                                  }
                                }}
                              </ElPopover>
                            </span>
                          </span>
                        )
                      }
                    }}
                  </ElTag>
                ))}
                {yAxisVisible.value ? (
                  <ElInput
                    ref={yAxisRef}
                    v-model={yAxisValue.value}
                    size="small"
                    style={{ width: '80px' }}
                    onBlur={() => {
                      this.props.option.yAxis.push({ name: yAxisValue.value })

                      yAxisValue.value = ''
                      yAxisVisible.value = false
                    }}
                  ></ElInput>
                ) : (
                  <ElButton
                    onClick={() => {
                      yAxisVisible.value = true
                      nextTick(() => {
                        yAxisRef.value!.input!.focus()
                      })
                    }}
                    type="warning"
                    size="small"
                    circle
                    icon={Plus}
                  ></ElButton>
                )}
              </div>
            </div>
            <div class={classes['params-item']}>
              <ElText class={classes['params-item-label']} type="info">
                系列名字段
              </ElText>
              <div class={classes['params-item-content']}>
                <ElButton
                  type="primary"
                  size="small"
                  onClick={() => {
                    const item = {
                      name: 'defaultName',
                      type: 'bar',
                      yAxisIndex: 0
                    }
                    this.props.option.series.push(item)
                  }}
                >
                  + 添加系列
                </ElButton>
                <br></br>
                {this.props.option.series.map((item, index) => (
                  <ElTag
                    key={item.name}
                    closable
                    type="primary"
                    onClose={() => this.props.option.series.splice(index, 1)}
                  >
                    {{
                      default: () => {
                        return (
                          <span
                            style={{
                              flex: '1',
                              display: 'flex',
                              justifyContent: 'space-between'
                            }}
                          >
                            <span>{item.name}</span>
                            <span>
                              <ElPopover
                                width={200}
                                trigger="click"
                                teleported={false}
                                placement="top"
                              >
                                {{
                                  reference: () => (
                                    <ElIcon color="var(--el-color-primary)">
                                      <Edit></Edit>
                                    </ElIcon>
                                  ),
                                  default: () => {
                                    // 循环组件有key，修改值会刷新
                                    const name = ref(item.name)

                                    return (
                                      <>
                                        <ElForm label-width="60px">
                                          <ElFormItem label="系列名">
                                            <ElInput
                                              v-model={name.value}
                                              size="small"
                                              onChange={(v) => (item.name = v)}
                                            ></ElInput>
                                          </ElFormItem>
                                          <ElFormItem label="y轴索引">
                                            <ElInputNumber
                                              v-model={item.yAxisIndex}
                                              min={0}
                                              max={this.props.option.yAxis.length - 1}
                                              size="small"
                                            ></ElInputNumber>
                                          </ElFormItem>
                                          <ElFormItem label="类型">
                                            <ElRadioGroup v-model={item.type} size="small">
                                              <ElRadioButton
                                                value="line"
                                                label="折线"
                                                size="small"
                                              ></ElRadioButton>
                                              <ElRadioButton
                                                value="bar"
                                                label="柱状"
                                                size="small"
                                              ></ElRadioButton>
                                              <ElRadioButton
                                                value="cube"
                                                label="立方"
                                                size="small"
                                              ></ElRadioButton>
                                              <ElRadioButton
                                                value="cylinder"
                                                label="圆柱"
                                                size="small"
                                              ></ElRadioButton>
                                            </ElRadioGroup>
                                          </ElFormItem>
                                        </ElForm>
                                      </>
                                    )
                                  }
                                }}
                              </ElPopover>
                            </span>
                          </span>
                        )
                      }
                    }}
                  </ElTag>
                ))}
              </div>
            </div>
            <div class={classes['params-item']}>
              <ElText class={classes['params-item-label']} type="info">
                柱条宽度
              </ElText>
              <div class={classes['params-item-content']}>
                <ElInputNumber
                  v-model={this.props.option.barWidth}
                  min={1}
                  size="small"
                ></ElInputNumber>
              </div>
            </div>
            <div class={classes['params-item']}>
              <ElText class={classes['params-item-label']} type="info">
                平滑
              </ElText>
              <div class={classes['params-item-content']}>
                <ElSwitch
                  modelValue={this.props.option.smooth}
                  onUpdate:modelValue={(v) => (this.props.option.smooth = v)}
                  size="small"
                ></ElSwitch>
              </div>
            </div>
            <div class={classes['params-item']}>
              <ElText class={classes['params-item-label']} type="info">
                坐标轴字色
              </ElText>
              <div class={classes['params-item-content']}>
                <ElColorPicker
                  modelValue={this.props.option.axisLabelColor}
                  onUpdate:modelValue={(v) => (this.props.option.axisLabelColor = v || '')}
                  show-alpha
                  size="small"
                  teleported={false}
                ></ElColorPicker>
              </div>
            </div>
            <div class={classes['params-item']}>
              <ElText class={classes['params-item-label']} type="info">
                图例字色
              </ElText>
              <div class={classes['params-item-content']}>
                <ElColorPicker
                  modelValue={this.props.option.legendTextStyleColor}
                  onUpdate:modelValue={(v) => (this.props.option.legendTextStyleColor = v || '')}
                  show-alpha
                  size="small"
                  teleported={false}
                ></ElColorPicker>
              </div>
            </div>
            <div class={classes['params-item']}>
              <ElText class={classes['params-item-label']} type="info">
                调色盘
              </ElText>
              <div class={classes['params-item-content']}>
                {this.props.option.color.map((c, index) => (
                  <ElColorPicker
                    modelValue={this.props.option.color[index]}
                    onUpdate:modelValue={(v) => (this.props.option.color[index] = v || '')}
                    color-format="hsl"
                    show-alpha
                    size="small"
                    teleported={false}
                  ></ElColorPicker>
                ))}
                <ElButton
                  type="primary"
                  icon={Plus}
                  circle
                  onClick={() => this.props.option.color.push('#5af')}
                  size="small"
                ></ElButton>
                <ElButton
                  type="danger"
                  icon={Minus}
                  circle
                  onClick={() => this.props.option.color.pop()}
                  size="small"
                ></ElButton>
              </div>
            </div>
            <div class={classes['params-item']}>
              <ElText class={classes['params-item-label']} type="info">
                线性渐变
                <Tip content={'索引位置调色盘为开始颜色，索引+1调色盘为结束颜色'}></Tip>
              </ElText>
              <div class={classes['params-item-content']}>
                <ElSwitch v-model={this.props.option.colorLinear} size="small"></ElSwitch>
              </div>
            </div>
            <div class={classes['params-item']}>
              <ElText class={classes['params-item-label']} type="info">
                轮流选择
              </ElText>
              <div class={classes['params-item-content']}>
                <ElSwitch v-model={this.props.autoAction} size="small"></ElSwitch>
              </div>
            </div>
          </pParams>
        )
      })
    )
  }

  toVue(): SfcObj {
    const sfcObj = super.toVue()
    const name = sfcObj.name
    const dataVar = sfcObj.dataVar
    const [uuid0, uuid1] = this.uuid.split('-')
    const optionVar = `${name}_${uuid0}_option`

    const optionStr = JSON.stringify(this.props.option)

    sfcObj.imports = {
      ...sfcObj.imports,
      vue: {
        ...sfcObj.imports.vue,
        ref: 'ref'
      },
      ['./imports/CartesianChart.vue']: {
        default: 'CartesianChart'
      }
    }

    sfcObj.importFiles = {
      ...sfcObj.importFiles,
      'CartesianChart.vue': CartesianChartRaw,
      'barRenderItem.js': barRenderItemRaw
    }

    sfcObj.script = `
${sfcObj.script}
const ${optionVar} = ref(${optionStr})
    `

    sfcObj.template = sfcObj.template.replace(
      '<slot></slot>',
      `<CartesianChart :option="${optionVar}" :data="${dataVar}" :autoAction="${this.props.autoAction}"></CartesianChart>`
    )

    return sfcObj
  }
}
